Operating systems are at the heart of all computer systems or computerized devices. An operating system provides an environment in which software applications are designed to operate. To that end, the operating system manages and schedules the resources of the computer or device it resides in, and provides various function modules and interfaces that can be used by the applications to accomplish their tasks.
Over the last two decades, computer operating systems, especially those for use on personal computers, have become increasingly sophisticated and powerful. Every new released version of an operating system tends to be a major step over the previous one, with the addition of numerous new features and functions. As operating systems become more powerful, they also grow tremendously in terms of size and complexity. For instance, the popular Microsoft DOS operating system of nearly two decades ago could fit on a few floppy disks. In contrast, the recent versions of the Microsoft Windows operating systems typically require tens of megabytes of storage and operation space and contain thousands of files, library functions, and program interfaces. As an operating system becomes bigger and more complicated, it is also more difficult for its developers to keep track of all the different modules and files of the operating system to ensure that they will work properly individually and together.
The difficulty of grappling with the complexity of a modern operating system is especially acute in the case of developing “embedded operating systems.” The term “embedded operating system” is commonly used to refer to a run-time image of an operating system that supports only a subset of functions and features of a full-fledged operating system developed for use on a regular computer. Embedded operating systems are needed for many different types of computerized devices, such as set-top boxes and information appliances. Those devices are typically fixed-function devices with limited resources. They do not need and also cannot support the rich functionality and flexibility of a regular operating system. By incorporating only those functions and resources needed by the fixed-function device on which it will run, the amount of storage, both persistent (e.g., Flash ROM or hard disk) and temporary (RAM), of an embedded operating system can be made much smaller than that of a regular operating system.
The conventional approach of developing embedded operating systems is to construct them using the binary modules or libraries of an existing regular operating system. Modules providing the functions needed by the device are selected and linked to form the run-time image. To that end, the developer of the embedded operating system is required to have knowledge of how each selected module should be included as a part of the run-time image, and the program responsible for creating the run-time image has to be coded accordingly to handle each module properly. This, however, can be a daunting task. Each module has its particular properties and requirements for resources, such as files to be copied and system settings (e.g., registry keys) to be set, etc. Moreover, the modules are often interdependent, i.e., the proper operation of one module depends on the existence or exclusion of other modules. Furthermore, multiple versions of a given module may have been created during the development process, and it is necessary to keep track of those versions so that a proper version can be selected for the target device. The developer of the embedded operating system has to know all these details about the modules of the regular operating system in order to properly use them in constructing the run-time image. As the regular operating system becomes more complex, keeping track of these details can be extremely difficult.
Furthermore, different devices often require different combinations of modules tailored for their specific functions. A program coded to construct a run-time image from a particular combination of existing modules suffers from inflexibility, as it cannot be used to handle different combinations. It is, however, impractical to attempt to code a program that knows how to handle every available module of the regular operating system so that it is capable of constructing run-time images from any combination of the modules.